#pragma once
namespace fastbird
{
	enum BUFFER_USAGE
	{
		BUFFER_USAGE_DEFAULT,
		BUFFER_USAGE_IMMUTABLE,
		BUFFER_USAGE_DYNAMIC,
		BUFFER_USAGE_STAGING,

		BUFFER_USAGE_COUNT
	};

	enum BUFFER_CPU_ACCESS_FLAG
	{
		BUFFER_CPU_ACCESS_NONE = 0,
		BUFFER_CPU_ACCESS_WRITE = 0x10000L,
		BUFFER_CPU_ACCESS_READ = 0x20000L
	};

	enum MAP_TYPE
	{
		MAP_TYPE_READ = 1,
		MAP_TYPE_WRITE = 2,
		MAP_TYPE_READ_WRITE = 3,
		MAP_TYPE_WRITE_DISCARD = 4,
		MAP_TYPE_WRITE_NO_OVERWRITE = 5
	};

	enum MAP_FLAG
	{
		MAP_FLAG_NONE = 0,
		MAP_FLAG_DO_NOT_WAIT = 0x100000L
	};

	struct MapData
	{
		void* pData;
		unsigned int rowPitch;
		unsigned int depthPitch;
	};

	enum PIXEL_FORMAT
	{
		PIXEL_FORMAT_R8G8B8A8,
		PIXEL_FORMAT_R8G8B8,
		PIXEL_FORMAT_COUNT
	};

	enum BINDING_SHADER
	{
		BINDING_SHADER_VERTEX_SHADER,
		BINDING_SHADER_PIXEL_SHADER,
		BINDING_SHADER_DOMAIN_SHADER,
		BINDING_SHADER_HULL_SHADER,
		BINDING_SHADER_GEOMETRY_SHADER,
		BINDING_SHADER_COMPUTE_SHADER,
		BINDING_SHADER_COUNT
	};

	inline BINDING_SHADER BindingShaderFromString(const char* szShader)
	{
		if (szShader==0)
		{
			return BINDING_SHADER_PIXEL_SHADER;
		}
		else if (stricmp(szShader, "vs")==0)
		{
			return BINDING_SHADER_VERTEX_SHADER;
		}
		else if (stricmp(szShader, "ps")==0)
		{
			return BINDING_SHADER_PIXEL_SHADER;
		}
		else if (stricmp(szShader, "ds")==0)
		{
			return BINDING_SHADER_DOMAIN_SHADER;
		}
		else if (stricmp(szShader, "hs")==0)
		{
			return BINDING_SHADER_HULL_SHADER;
		}
		else if (stricmp(szShader, "gs")==0)
		{
			return BINDING_SHADER_GEOMETRY_SHADER;
		}
		else if (stricmp(szShader, "cs")==0)
		{
			return BINDING_SHADER_COMPUTE_SHADER;
		}

		return BINDING_SHADER_PIXEL_SHADER;
	}

	enum FILL_MODE
	{
		FILL_MODE_WIREFRAME=2,
		FILL_MODE_SOLID=3,
	};

	enum CULL_MODE
	{
		CULL_MODE_NONE=1,
		CULL_MODE_FRONT=2,
		CULL_MODE_BACK=3
	};

	enum TEXTURE_TYPE
	{
		TEXTURE_TYPE_DEFAULT=0,
		TEXTURE_TYPE_COLOR_RAMP=1,
	};

	inline TEXTURE_TYPE TextureTypeFromString(const char* str)
	{
		if (str==0)
			return TEXTURE_TYPE_DEFAULT;
		if (stricmp(str, "ColorRamp")==0)
			return TEXTURE_TYPE_COLOR_RAMP;
		else if (stricmp(str, "Default")==0)
			return TEXTURE_TYPE_DEFAULT;

		return TEXTURE_TYPE_DEFAULT;
	}
	
	enum TEXTURE_FILTER
	{
		TEXTURE_FILTER_MIN_MAG_MIP_POINT	= 0,
		TEXTURE_FILTER_MIN_MAG_POINT_MIP_LINEAR	= 0x1,
		TEXTURE_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT	= 0x4,
		TEXTURE_FILTER_MIN_POINT_MAG_MIP_LINEAR	= 0x5,
		TEXTURE_FILTER_MIN_LINEAR_MAG_MIP_POINT	= 0x10,
		TEXTURE_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR	= 0x11,
		TEXTURE_FILTER_MIN_MAG_LINEAR_MIP_POINT	= 0x14,
		TEXTURE_FILTER_MIN_MAG_MIP_LINEAR	= 0x15,
		TEXTURE_FILTER_ANISOTROPIC	= 0x55,
		TEXTURE_FILTER_COMPARISON_MIN_MAG_MIP_POINT	= 0x80,
		TEXTURE_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR	= 0x81,
		TEXTURE_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT	= 0x84,
		TEXTURE_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR	= 0x85,
		TEXTURE_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT	= 0x90,
		TEXTURE_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR	= 0x91,
		TEXTURE_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT	= 0x94,
		TEXTURE_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR	= 0x95,
		TEXTURE_FILTER_COMPARISON_ANISOTROPIC	= 0xd5
	};

	inline TEXTURE_FILTER FilterFromString(const char* sz)
	{
		if (sz==0)
			return TEXTURE_FILTER_MIN_MAG_MIP_LINEAR;
		else if(stricmp(sz, "MIN_MAG_MIP_POINT")==0)
			return TEXTURE_FILTER_MIN_MAG_MIP_POINT;
		else if(stricmp(sz, "MIN_MAG_POINT_MIP_LINEAR")==0)
			return TEXTURE_FILTER_MIN_MAG_POINT_MIP_LINEAR;
		else if(stricmp(sz, "MIN_POINT_MAG_LINEAR_MIP_POINT")==0)
			return TEXTURE_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT;
		else if(stricmp(sz, "MIN_POINT_MAG_MIP_LINEAR")==0)
			return TEXTURE_FILTER_MIN_POINT_MAG_MIP_LINEAR;
		else if(stricmp(sz, "MIN_LINEAR_MAG_MIP_POINT")==0)
			return TEXTURE_FILTER_MIN_LINEAR_MAG_MIP_POINT;
		else if(stricmp(sz, "MIN_LINEAR_MAG_POINT_MIP_LINEAR")==0)
			return TEXTURE_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR;
		else if(stricmp(sz, "MIN_MAG_LINEAR_MIP_POINT")==0)
			return TEXTURE_FILTER_MIN_MAG_LINEAR_MIP_POINT;
		else if(stricmp(sz, "MIN_MAG_MIP_LINEAR")==0)
			return TEXTURE_FILTER_MIN_MAG_MIP_LINEAR;
		else if(stricmp(sz, "ANISOTROPIC")==0)
			return TEXTURE_FILTER_ANISOTROPIC;
		else if(stricmp(sz, "COMPARISON_MIN_MAG_MIP_POINT")==0)
			return TEXTURE_FILTER_COMPARISON_MIN_MAG_MIP_POINT;
		else if(stricmp(sz, "COMPARISON_MIN_MAG_POINT_MIP_LINEAR")==0)
			return TEXTURE_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR;
		else if(stricmp(sz, "COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT")==0)
			return TEXTURE_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT;
		else if(stricmp(sz, "COMPARISON_MIN_POINT_MAG_MIP_LINEAR")==0)
			return TEXTURE_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR;
		else if(stricmp(sz, "COMPARISON_MIN_LINEAR_MAG_MIP_POINT")==0)
			return TEXTURE_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT;
		else if(stricmp(sz, "COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR")==0)
			return TEXTURE_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR;
		else if(stricmp(sz, "COMPARISON_MIN_MAG_LINEAR_MIP_POINT")==0)
			return TEXTURE_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT;
		else if(stricmp(sz, "COMPARISON_MIN_MAG_MIP_LINEAR")==0)
			return TEXTURE_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR;
		else if(stricmp(sz, "COMPARISON_ANISOTROPIC")==0)
			return TEXTURE_FILTER_COMPARISON_ANISOTROPIC;

		return TEXTURE_FILTER_MIN_MAG_MIP_LINEAR;
	}

	enum TEXTURE_ADDRESS_MODE
	{
		TEXTURE_ADDRESS_WRAP	= 1,
		TEXTURE_ADDRESS_MIRROR	= 2,
		TEXTURE_ADDRESS_CLAMP	= 3,
		TEXTURE_ADDRESS_BORDER	= 4,
		TEXTURE_ADDRESS_MIRROR_ONCE	= 5
	};

	inline TEXTURE_ADDRESS_MODE AddressModeFromString(const char* sz)
	{
		if (sz==0)
			return TEXTURE_ADDRESS_CLAMP;
		else if (stricmp(sz, "Wrap")==0)
			return TEXTURE_ADDRESS_WRAP;
		else if (stricmp(sz, "Mirror")==0)
			return TEXTURE_ADDRESS_MIRROR;
		else if (stricmp(sz, "Clamp")==0)
			return TEXTURE_ADDRESS_CLAMP;
		else if (stricmp(sz, "Border")==0)
			return TEXTURE_ADDRESS_BORDER;
		else if (stricmp(sz, "Mirror_Once")==0)
			return TEXTURE_ADDRESS_MIRROR_ONCE;

		return TEXTURE_ADDRESS_CLAMP;
	}

	enum COMPARISON_FUNC
	{
		COMPARISON_NEVER	= 1,
		COMPARISON_LESS	= 2,
		COMPARISON_EQUAL	= 3,
		COMPARISON_LESS_EQUAL	= 4,
		COMPARISON_GREATER	= 5,
		COMPARISON_NOT_EQUAL	= 6,
		COMPARISON_GREATER_EQUAL	= 7,
		COMPARISON_ALWAYS	= 8
	};

	enum BLEND
	{
		BLEND_ZERO               = 1,
		BLEND_ONE                = 2,
		BLEND_SRC_COLOR          = 3,
		BLEND_INV_SRC_COLOR      = 4,
		BLEND_SRC_ALPHA          = 5,
		BLEND_INV_SRC_ALPHA      = 6,
		BLEND_DEST_ALPHA         = 7,
		BLEND_INV_DEST_ALPHA     = 8,
		BLEND_DEST_COLOR         = 9,
		BLEND_INV_DEST_COLOR     = 10,
		BLEND_SRC_ALPHA_SAT      = 11,
		BLEND_BLEND_FACTOR       = 14,
		BLEND_INV_BLEND_FACTOR   = 15,
		BLEND_SRC1_COLOR         = 16,
		BLEND_INV_SRC1_COLOR     = 17,
		BLEND_SRC1_ALPHA         = 18,
		BLEND_INV_SRC1_ALPHA     = 19 
	};

	enum BLEND_OP
	{
		BLEND_OP_ADD            = 1,
		BLEND_OP_SUBTRACT       = 2,
		BLEND_OP_REV_SUBTRACT   = 3,
		BLEND_OP_MIN            = 4,
		BLEND_OP_MAX            = 5
	};

	enum COLOR_WRITE_ENABLE
    {
		COLOR_WRITE_ENABLE_RED	= 1,
		COLOR_WRITE_ENABLE_GREEN	= 2,
		COLOR_WRITE_ENABLE_BLUE	= 4,
		COLOR_WRITE_ENABLE_ALPHA	= 8,
		COLOR_WRITE_ENABLE_ALL	= ( ( ( COLOR_WRITE_ENABLE_RED | COLOR_WRITE_ENABLE_GREEN )  | COLOR_WRITE_ENABLE_BLUE )  | COLOR_WRITE_ENABLE_ALPHA ) 
    };

	enum PRIMITIVE_TOPOLOGY
	{
		PRIMITIVE_TOPOLOGY_POINTLIST,
		PRIMITIVE_TOPOLOGY_LINELIST,
		PRIMITIVE_TOPOLOGY_LINESTRIP,
		PRIMITIVE_TOPOLOGY_TRIANGLELIST,
		PRIMITIVE_TOPOLOGY_TRIANGLESTRIP,
	};

	enum INPUT_ELEMENT_FORMAT
	{
		INPUT_ELEMENT_FORMAT_FLOAT3,
		INPUT_ELEMENT_FORMAT_UBYTE4,
		INPUT_ELEMENT_FORMAT_FLOAT2,
		INPUT_ELEMET_FORMAT_INT4,
	};

	enum INPUT_CLASSIFICATION
	{
		INPUT_CLASSIFICATION_PER_VERTEX_DATA,
		INPUT_CLASSIFICATION_PER_INSTANCE_DATA
	};
}